home *** CD-ROM | disk | FTP | other *** search
-
- /* This version of AMarqueeDebug creates the QSession, then
- spawns a child thread and hands control of the QSession
- to the child thread via QDetachSession() and QReattachSession().
- There aren't any advantages to doing it this way, except
- to show how (and that ;)) QDetachSession() and QReattachSession()
- work.
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
-
- #include <clib/AMarquee_protos.h>
-
- #include <pragmas/AMarquee_pragmas.h>
-
- #include "include:signal.h"
-
- struct Library * AMarqueeBase = NULL;
- struct QSession * session = NULL;
- BOOL waitForChildThread = TRUE;
-
- /* Takes user input until blank line is typed */
- void ProcessDebugCommands(struct QSession * session)
- {
- while(1)
- {
- char debugline[500] = "\0\0\0\0\0\0\0\0";
- char * keyword, * data;
- ULONG dataLen = 0L;
- LONG res;
-
- printf("Enter your debug command now: "); fflush(stdout);
- gets(debugline);
-
- keyword = &debugline[2];
- if (data = strchr(keyword,'='))
- {
- *data = '\0'; /* terminate the keyword */
- data++;
- dataLen = strlen(data)+1;
- }
- switch((int)(debugline[0]))
- {
- case '\0': res=QGo(session,0L); break;
- case 'A': res=QSetMessageAccessOp(session, keyword, -1); break;
- case 'm': res=QMessageOp(session, keyword, data, dataLen); break;
- case 'M': res=QSysMessageOp(session, keyword, data); break;
- case 'a': res=QSetAccessOp(session, keyword); break;
- case 's': res=QSetOp(session, keyword, data, dataLen); break;
- case 'S': res=QStreamOp(session, keyword, data, dataLen); break;
- case 'r': res=QRenameOp(session, keyword, data); break;
- case 'D': res=QDebugOp(session, keyword); break;
- case 'g': res=QGetOp(session, keyword, -1); break;
- case 'd': res=QDeleteOp(session, keyword); break;
- case 'i': res=QInfoOp(session); break;
- case 'c': res=QSubscribeOp(session, keyword, -1); break;
- case 'C': res=QGetAndSubscribeOp(session, keyword, -1); break;
- case 'k': res=QClearSubscriptionsOp(session,atoi(keyword)); break;
- case 'p': res=QPingOp(session); break;
- case 'v': res=QRequestPrivilegesOp(session,atol(keyword)); break;
- case 'w': res=QReleasePrivilegesOp(session,atol(keyword)); break;
- case '!': res=QKillClientsOp(session,keyword); break;
- case '?': res=QGetParameterOp(session,keyword); break;
- case '$': res=QSetParameterOp(session,keyword,data); break;
- default: printf("Command code %c was not recognized.\n",debugline[0]); break;
- }
- printf("(Op result was %i)\n",res);
- if (debugline[0] == '\0') return;
- }
- }
-
-
-
- __geta4 void ChildThreadEntryFunc(void)
- {
- if (QReattachSession(session, 0L) == FALSE) printf("Error: QReattachSession failed! Press CTRL-C to exit.\n");
- else
- {
- printf("Child thread is running!\n");
- while(1)
- {
- struct QMessage * qMsg;
- ULONG signals = (1L << session->qMsgPort->mp_SigBit) | (SIGBREAKF_CTRL_C) | (SIGBREAKF_CTRL_F);
-
- /* Wait for next message from the server */
- signals = Wait(signals);
- if (signals & (1L << session->qMsgPort->mp_SigBit))
- {
- while(qMsg = (struct QMessage *) GetMsg(session->qMsgPort))
- {
- struct QRunInfo * inf = (qMsg->qm_DataLen == sizeof(struct QRunInfo)) ? ((struct QRunInfo *) qMsg->qm_Data) : NULL;
-
- /* Handle message */
- printf("Message %p recieved---------\n",qMsg);
- printf("Status: %i (%s)\n", qMsg->qm_Status, QErrorName(qMsg->qm_Status));
- printf("Error Line: %i\n", qMsg->qm_ErrorLine);
- printf("Message ID: %i\n", qMsg->qm_ID);
- printf("Path: [%s]\n", qMsg->qm_Path?qMsg->qm_Path:"<NULL>");
- printf("Data: [%s](int=%i)\n", qMsg->qm_Data?qMsg->qm_Data:((UBYTE*)"<NULL>"),qMsg->qm_Data?(*((int*)qMsg->qm_Data)):0);
- printf("DataLen: %lu\n", qMsg->qm_DataLen);
- printf("ActualLen: %lu\n", qMsg->qm_ActualLen);
-
- if (inf) printf("Info: alloced:%li allowed:%li avail:%li curPrivs=0x%x posPrivs=0x%x\n",
- inf->qr_Alloced, inf->qr_Allowed, inf->qr_Avail, inf->qr_CurrentPrivs, inf->qr_PossiblePrivs);
- FreeQMessage(session, qMsg);
- }
- }
- if (signals & SIGBREAKF_CTRL_F) ProcessDebugCommands(session);
- if (signals & SIGBREAKF_CTRL_C) break; /* Quit if CTRL-C pressed */
- }
-
- #ifdef LET_CHILD_THREAD_FREE_THE_QSESSION
- printf("Freeing QSession in child thread...\n");
- QFreeSession(session);
- session = NULL; /* So that the main thread won't try to free it */
- #else
- if (QDetachSession(session, 0L) == FALSE) printf("Warning: Child's QDetachSession failed!\n");
- /* Now the main thread is able to free the QSession. */
- #endif
- }
-
- printf("Child thread is exiting...\n");
-
- /* Signals main thread to wake up... hacky method but it's just for this test proggy */
- Forbid(); /* to make sure our thread has died before the code gets unloaded! */
- waitForChildThread = FALSE;
- }
-
- /* Main program */
- int main(int argc, char ** argv)
- {
- char * connectTo, * progName;
- int port;
-
- printf("Usage Note: AMarqueeDebugMultiThread [hostname=localhost] [myname=debug] [port=2957]\n");
- signal(SIGINT, SIG_IGN); /* Don't let DICE abort us abruptly */
-
- connectTo = (argc>1) ? argv[1] : "localhost";
- progName = (argc>2) ? argv[2] : "debug";
- port = (argc>3) ? atoi(argv[3]) : 2957;
-
- if ((AMarqueeBase = OpenLibrary("amarquee.library",47L)) == NULL)
- {
- printf("Couldn't open amarquee.library v47!\n");
- exit(RETURN_ERROR);
- }
- printf("Connecting to %s:%i (allocating QSession in main thread)\n",connectTo, port);
- if ((session = QNewSession(connectTo, port, progName)) == NULL)
- {
- printf("Couldn't connect to server %s:%i\n",connectTo, port);
- exit(RETURN_WARN);
- }
- printf("Connected to server %s:%i\n",connectTo, port);
-
- /* Setup some sample data */
- (void)QSetOp(session, "sampledata", "Kids", 5);
- (void)QSetOp(session, "sampledata/Jeremy", "1", 2);
- (void)QSetOp(session, "sampledata/Joanna", "2", 2);
- (void)QSetOp(session, "sampledata/Joanna/nerd", "yep! :)", 8);
- (void)QSetOp(session, "sampledata/Joellen", "3", 2);
- (void)QSetOp(session, "sampledata/Charcoal", "Kitty!", 7);
- (void)QGetOp(session, "/#?/#?/#?/#?", -1);
- (void)QGo(session, 0L);
-
- printf("Commands are:\n");
- printf("\n");
- printf("a wildhostpath Access control (default is /#?/#?)\n");
- printf("A wildhostpath Access control for incoming messages (default in no access)\n");
- printf("m hosts=data Send an active message to hosts\n");
- printf("M hosts=string Send an system message to hosts\n");
- printf("s path=data Set data node value\n");
- printf("S path=data Stream data node value\n");
- printf("r path=newlabel Rename data node\n");
- printf("D debugstring Send debug string\n");
- printf("g wildpath Get a node or nodes\n");
- printf("c wildpath Subscribe to a node or nodes\n");
- printf("C wildpath Get&Subscribe to a node or nodes\n");
- printf("k opID Klear subscriptions (by id or 0 for all)\n");
- printf("d wildpath Delete a node or nodes\n");
- printf("i Request info packet\n");
- printf("p Request ping packet\n");
- printf("v # Request new privileges (by code bitchord)\n");
- printf("w # Release existing privileges (by code bitchord)\n");
- printf("! hosts Kill other clients (requires KILLCLIENTS privilege!)\n");
- printf("$ param=string Set a parameter with QSetParam()\n");
- printf("? param Get a parameter by name\n");
- printf("<enter> Send accumulated transactions (GO!!)\n");
- printf("\n");
- printf("Press CTRL-F to enter commands, or CTRL-C to quit\n");
-
- if (QDetachSession(session, 0L)) /* Make the QSession available to other threads */
- {
- struct Task * childThread;
-
- printf("Spawning child thread...\n");
- if (childThread = CreateNewProcTags(NP_Entry, ChildThreadEntryFunc, NP_Name, "AMarqueeDebugMultiThread Child Process", TAG_END, NULL))
- {
- BOOL childGone = FALSE;
-
- while(1)
- {
- ULONG sigs = Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F);
-
- if (sigs & SIGBREAKF_CTRL_C)
- {
- break;
- }
- if (sigs & SIGBREAKF_CTRL_F) Signal(childThread, SIGBREAKF_CTRL_F);
- }
-
- printf("Main thread is waiting for child thread to die now.\n");
- while(childGone == FALSE)
- {
- Delay(10);
- Forbid();
- if (waitForChildThread) Signal(childThread, SIGBREAKF_CTRL_C);
- else childGone = TRUE;
- Permit();
- }
- }
- }
- else printf("Error, couldn't Detach QSession from main thread\n");
-
- printf("\nCleaning up...\n");
- if (session)
- {
- printf("Main thread is freeing the QSession.\n");
- /* This MUST be done before we close the library.
- Furthermore, it must be done by the thread
- the Qsession is attached to (it can be done by any
- thread if the QSession is detached) */
- QFreeSession(session);
- }
- if (AMarqueeBase) CloseLibrary(AMarqueeBase);
- printf("All done.\n");
-
- return(0);
- }
-
-